home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / ASTRONOM / H139.ZIP / RO101.ZIP / RO_DIVE.C < prev    next >
C/C++ Source or Header  |  1991-11-04  |  11KB  |  472 lines

  1. /********************************************************/
  2. /*                            */
  3. /*    ro_dive.c    diversion and register routines    */
  4. /*            for ro                */
  5. /*                            */
  6. /*    ro version 1.10                    */
  7. /*                            */
  8. /*    Portions copyright (c) 1989 by Ted A. Campbell    */
  9. /*        Bywater Software            */
  10. /*        P. O. Box 4023                */
  11. /*        Duke Station                */
  12. /*        Durham, NC  27706            */
  13. /*                            */
  14. /*    Contains portions of ROFF4, Version 1.60    */
  15. /*      (c) 1983, 4 by Ernest E. Bergmann               */
  16. /*        Physics, Building #16            */
  17. /*        Lehigh University            */
  18. /*        Bethlehem, Pa. 18015            */
  19. /*                            */
  20. /*    Contains portions of ROFF4, Version 1.61    */
  21. /*      (c) 1985 by Konrad Kwok                         */
  22. /*        20 3rd Street, Section M        */
  23. /*        Fariview Park,                */
  24. /*        Hong Kong                */
  25. /*                            */
  26. /*    ro and its predecessor ROFF4 are based on     */
  27. /*    the ROFF text processor described in Kernigan    */
  28. /*    and Plauger's now-classic text <Software Tools> */
  29. /*                            */
  30. /* Permission is hereby granted for all commercial and    */
  31. /* non-commercial reproduction and distribution of this */
  32. /* material provided this notice is included.        */
  33. /*                            */
  34. /********************************************************/
  35.  
  36. #include "ro.h"
  37.  
  38. /****************************************/
  39. /* checks RLIST; creates new entry if needed;
  40.    returns pointer to integer variable */
  41.  
  42. int *
  43. regist( s )    
  44.    char *s;
  45.    {
  46.    struct divfd *pw;
  47.    int *pi;
  48.    struct divfd *sptr;
  49.  
  50.    pw = find2( s, rlink );   
  51.  
  52.    if ( pw != NULL ) 
  53.       {
  54.       return( &( pw->val ) );
  55.       }
  56.  
  57.    /*  else create new entry */
  58.  
  59.    if ( ( sptr = (struct divfd *) malloc( (size_t) sizeof( struct divfd ))) == NULL )
  60.       {
  61.       fprintf( stderr, "Fatal error: cannot allocate memory for register structure.  \n" );
  62.       exit ( -1 );
  63.       }
  64.    sptr->prev = rlink;      /* save previous link   */
  65.    strcpy( sptr->nm, s );      /* copy register name to structure */
  66.    sptr->bf = NULL;      /* not a stream */
  67.    sptr->mstr = NULL;      /* and not a macro */
  68.    rlink = sptr;         /* set new link    */
  69.    pi = &(sptr->val);
  70.    *pi = REGDEF;
  71.    return( pi );
  72.    }
  73.  
  74. /****************************************/
  75. /* process .nr request                  */
  76.  
  77. dovar()
  78.    {
  79.    static char wbuf[MAXLINE];
  80.    static int typ;
  81.    int val, *pw;
  82.    getwrd( ro_curline, wbuf );
  83.    skip_blanks( ro_curline );
  84.    val = get_val( ro_curline, &typ );
  85.    getwrd( ro_curline, wbuf);
  86.    if ( wbuf[0] == NUMSIGN && wbuf[1] == '\0' )
  87.       {
  88.       set( &ro_newpag, val, typ, ro_newpag, 1, 9999);
  89.       }
  90.    else
  91.       {
  92.       pw = (int *) regist(wbuf);
  93.       set( pw, val, typ, REGDEF, 0, 9999);
  94.       }
  95.    }
  96.  
  97. preregister( name, value )
  98.    char *name;
  99.    int value;
  100.    {
  101.    int *pw;
  102.    pw = (int *) regist( name );
  103.    *pw = value;
  104.    }
  105.  
  106. /****************************************/
  107. /* process .di version */
  108.  
  109. dodiv()
  110.    {
  111.    char wbuf[MAXLINE], *pc;
  112.    struct divfd *pd;
  113.    int p;
  114.  
  115.    getwrd( ro_curline, wbuf );
  116.    if ( getwrd( ro_curline, wbuf) != WE_HAVE_A_WORD )
  117.       {
  118.       strcpy( wbuf, "div.$$$");
  119.       fprintf( stderr,".di:  no name, %s assumed\n",
  120.          wbuf);
  121.       }
  122.    if ( strlen( wbuf ) > 2 )
  123.       {
  124.       wbuf[ 2 ] = '\0';
  125.       if ( ro_verbose )
  126.          {
  127.          fprintf( stderr,
  128.             ".di:  name over two characters shortened to <%s> \n",
  129.             wbuf );
  130.          }
  131.       }   
  132.  
  133.    if ( ( pd = find2( wbuf, dlink )) != NULL ) /*if in table*/
  134.       {
  135. #ifdef   DEBUG
  136.       if ( ro_debug == TRUE )
  137.          {
  138.          fprintf( stderr, "DEBUG:  diversion <%s> found. \n",
  139.             wbuf );
  140.          }
  141. #endif
  142.       if ( ( pd->bf == NULL ))      /* file not open */
  143.          {
  144.          if (( pd->bf = fopen( pd->fn, "w" )) != NULL)
  145.             {
  146. #ifdef   DEBUG
  147.             if ( ro_debug == TRUE )
  148.                {
  149.                fprintf( stderr, "DEBUG:  .di:  <%s> reopened for diversion.\n", pd->fn );
  150.                }
  151. #endif
  152.             }
  153.          else
  154.             {
  155.             fprintf( stderr, "Fatal error:  <%s> cannot be rewritten\n",wbuf);
  156.             exit( -1 );
  157.             }
  158.          }
  159.       }
  160.    else         /* not in table, build new entry */
  161.       {
  162.  
  163.       if ( ( pd = (struct divfd *) malloc( (size_t) sizeof( struct divfd ))) == NULL )
  164.          {
  165.          fprintf( stderr, "Fatal error: cannot allocate memory for diversion structure.  \n" );
  166.          exit ( -1 );
  167.          }
  168.  
  169.       pd->prev = dlink;      /* save previous link   */
  170.       strcpy( pd->nm, wbuf );      /* save name      */
  171.       dlink = pd;         /* set new link    */
  172.       pd->mstr = NULL;      /* not a macro      */
  173.       pd->ls = pd->cs = 0;      /* set these to 0       */
  174.       strcpy( pd->fn, wbuf );      /* get name in filename */
  175.       strcat( pd->fn, "_ro.div" );   /* make unique diversion name */
  176.  
  177.       if (( pd->bf = fopen( pd->fn, "w" )) == NULL )
  178.          {
  179.          fprintf( stderr, 
  180.             "Fatal error:  Can't create diversion file <%s>.\n", pd->fn );
  181.          exit( -1 );
  182.          }
  183.       }
  184.  
  185.    /*** from this point we may presume a valid structure and file */
  186.  
  187.    while ( ro_gets( ro_curline ) != NULL )
  188.       {
  189.       if (( *ro_curline == COMMAND ) && ( comtyp( ro_curline ) == DI )) 
  190.          {
  191.  
  192.          /*** NESTING of diversions not currently supported; 
  193.               implementation would require testing at this point 
  194.               for argument to .di ***/
  195.  
  196.          break;
  197.          }
  198.       if ( pc = (char *) macq( ro_curline))   /* if macro   */
  199.          {
  200.          pbmac( pc, ro_curline);   /* process macro */
  201.          continue;
  202.          }
  203.  
  204.       /*else*/
  205.  
  206.       p = strlen( ro_curline );
  207.       ro_curline[ p ] = '\n';      /* terminate the line with CR */
  208.       ++p;
  209.       ro_curline[ p ] = '\0';      /* and then '\0' */
  210.       fputs( ro_curline, pd->bf );   /* and put to diversion file */
  211.       ( pd->ls )++;         /* increment line counter */
  212.       ( pd->cs ) += strlen( ro_curline ); /* and char counter */
  213.       }
  214.    }
  215.  
  216. /****************************************/
  217. /* read from diversion                  */
  218.  
  219. read_div( sptr )
  220.    struct divfd *sptr;
  221.    {
  222.    if ( sptr->bf != NULL )
  223.       {
  224.       dclose( sptr );
  225.       }
  226.  
  227. #ifdef   DEBUG
  228.    if ( ro_debug == TRUE )
  229.       {
  230.       fprintf( stderr, "DEBUG:  reading from diversion <%s>, file <%s> \n",
  231.          sptr->nm, sptr->fn );
  232.       }
  233. #endif
  234.  
  235.    if ( ro_fptr < FMAX ) 
  236.       {
  237.       ro_fstack[ ro_fptr++ ] = instream;
  238.       }
  239.    else   
  240.       {
  241.       fprintf( stderr,"Fatal error:  ro_fstack overflow\n");
  242.       exit( -1 );
  243.       }
  244.  
  245.    if (( instream = fopen( sptr->fn, "r" )) != NULL ) 
  246.       {
  247.       return;      /* file opened successfully */
  248.       }
  249.  
  250.    /* else the attempt has failed */
  251.  
  252.    if ( ro_verbose )
  253.       {
  254.       fprintf( stderr, ".%s:  can't open <%s>\n", sptr->nm, sptr->fn );
  255.       }
  256.    endso();
  257.  
  258.    }
  259.  
  260. /****************************************/
  261. /* .so -- read from source file         */
  262.  
  263. source()
  264.    {
  265.    char name[ MAXLINE ];
  266.  
  267.    getwrd( ro_curline, name );
  268.    if( getwrd( ro_curline, name ) != WE_HAVE_A_WORD)
  269.       {
  270.       if ( ro_verbose )
  271.          {
  272.          fprintf( stderr,".so has no name\n");
  273.          }
  274.       return -1;
  275.       }
  276.  
  277.    if ( ro_fptr < FMAX ) 
  278.       {
  279.       ro_fstack[ ro_fptr++ ] = instream;
  280.       }
  281.    else   
  282.       {
  283.       fprintf( stderr,"Fatal error:  ro_fstack overflow\n");
  284.       exit( -1 );
  285.       }
  286.  
  287.    if (( instream = fopen( name, "r" )) != NULL ) 
  288.       {
  289.       return;
  290.       }
  291.  
  292.    /* else the attempt has failed */
  293.  
  294.    if ( ro_verbose )
  295.       {
  296.       fprintf( stderr, ".so:  can't open <%s>\n", name );
  297.       }
  298.    endso();
  299.    }
  300.  
  301. /****************************************/
  302.  
  303. showr() /*lists register names and contents*/
  304.    {
  305.    struct divfd *pw;
  306.    fprintf( stderr, "REGISTERS and <values>:\n");
  307.    pw = rlink;
  308.    while ( pw != NULL )
  309.       {
  310.       fprintf( stderr, "%s:\t<%d> \n",pw->nm, pw->val );
  311.       pw = pw->prev;
  312.       }
  313.    dashes();
  314.    }
  315.  
  316. /****************************************/
  317.  
  318. showd() /*shows all diversions and status*/
  319.    {
  320.    struct divfd *pd;
  321.  
  322.    fprintf( stderr, "Diversion files:\n");
  323.    pd = dlink;
  324.    while( pd != NULL )
  325.       {
  326.       fprintf( stderr, "%s:\t", pd->nm );
  327.       fprintf( stderr, "%d characters, %d lines [",
  328.       pd->cs, pd->ls );
  329.       if( pd->bf ) 
  330.          {
  331.          fprintf( stderr, "open]\n");
  332.          }
  333.       else   
  334.          {
  335.          fprintf( stderr, "closed]\n");
  336.          }
  337.       pd = pd->prev;
  338.       }
  339.    dashes();
  340.    }
  341.  
  342. /****************************************/
  343. /* flushes and closes all open diversions, */
  344. /* erases diversion files */
  345.  
  346. dsclose()    
  347.    {
  348.    struct divfd *pd;
  349.  
  350. #ifdef   DEBUG
  351.    if ( ro_debug == TRUE )
  352.       {
  353.       fprintf( stderr, "DEBUG:  dsclose called \n" );
  354.       }
  355. #endif
  356.  
  357.    pd = dlink;
  358.    while( pd != NULL )
  359.       {
  360.  
  361.       /*** Close the diversion ***/
  362.  
  363.       dclose( pd );
  364.  
  365.       /*** Erase diversion file ***/
  366.  
  367. #ifdef   DEBUG
  368.       if ( ro_debug == TRUE )
  369.          {
  370.          fprintf( stderr, "DEBUG:  Ready to erase diversion file <%s> \n",
  371.             pd->fn );
  372.          }
  373. #endif
  374.       if ( unlink( pd->fn ) == -1 )
  375.          {
  376.          if ( ro_verbose == TRUE )
  377.             {
  378.             fprintf( stderr, "Failed to erase diversion file <%s> \n",
  379.                pd->fn );
  380.             }
  381.          }
  382.       else
  383.              {
  384. #ifdef   DEBUG
  385.          if ( ro_debug == TRUE )
  386.             {
  387.             fprintf( stderr, "DEBUG:  Erased diversion file <%s> \n",
  388.                pd->fn );
  389.             }
  390. #endif
  391.          }
  392.  
  393.       pd = pd->prev;
  394.       }
  395.    }
  396.  
  397. /****************************************/
  398.  
  399. dclose( pd )      /*flushes and closes diversion*/
  400.    struct divfd *pd;
  401.    {
  402.    if ( pd && ( !( pd->bf ))) 
  403.       {
  404.       return(FALSE);
  405.       }
  406.  
  407. #ifdef   DEBUG
  408.    if ( ro_debug == TRUE )
  409.       {
  410.       fprintf( stderr, "DEBUG:  Closing diversion %s \n", pd->nm );
  411.       }
  412. #endif
  413.  
  414.    /*** Close the diversion File ***/      
  415.  
  416.    if ( pd->bf != NULL )
  417.       {
  418.  
  419.       fflush( pd->bf );      /* Flush the stream      */
  420.  
  421.       if ( fclose( pd->bf ) == ERROR ) /* Close the file      */
  422.          {
  423.          if ( ro_verbose == TRUE )
  424.             {
  425.             fprintf( stderr, "Failed to close diversion <%s>! \n",
  426.                pd->nm );
  427.             }
  428.          }
  429. #ifdef   DEBUG
  430.       else if ( ro_debug == TRUE )
  431.          {
  432.          fprintf( stderr, "DEBUG:  Closed [O.K.]\n");
  433.          }
  434. #endif
  435.       }
  436.  
  437.    pd->bf = NULL;         /* Set file pointer to NULL   */
  438.    return( TRUE );         /* Indicate successful completion */
  439.    }
  440.  
  441. /****************************************/
  442. /* convert string to upper case */
  443.  
  444. ucstr(s)
  445.    char *s;
  446.    {
  447.    while(*s)
  448.       {
  449.       *s = toupper(*s);
  450.       s++;
  451.       }
  452.    }
  453.  
  454. /****************************************/
  455.  
  456. endso() /*called upon EOF to return to previous input file*/
  457.    {
  458.    if ( ro_fptr )
  459.       {
  460.       fclose( instream );
  461.       instream = ro_fstack[ --ro_fptr ];
  462.       }
  463.    ro_binp = 0;
  464.    }
  465.  
  466. /****************************************/
  467.  
  468. dashes()
  469.    {
  470.    fprintf( stderr, "-----------\n");
  471.    }
  472.